home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / STEP17.PAK / STEP17DV.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  34KB  |  1,488 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1994 by Borland International
  3. //   Tutorial application -- step17dv.cpp
  4. //   Automation Container Server example
  5. //----------------------------------------------------------------------------
  6. #include <owl/pch.h>
  7. #include <owl/dc.h>
  8. #include <owl/inputdia.h>
  9. #include <owl/chooseco.h>
  10. #include <owl/gdiobjec.h>
  11. #include <owl/docmanag.h>
  12. #include <owl/listbox.h>
  13. #include <owl/controlb.h>
  14. #include <owl/buttonga.h>
  15. #include <owl/scroller.h>  // scrolling support
  16. #include <classlib/arrays.h>
  17. #include <owl/olemdifr.h>
  18. #include <owl/oledoc.h>
  19. #include <owl/oleview.h>
  20. #include <ocf/automacr.h>
  21. #include <ocf/ocdata.h>
  22. #include <ocf/ocremvie.h>
  23. #include <owl/edit.rh>
  24. #include "step17dv.h"
  25. #include "step17.h"
  26. #include "step17dv.rc"
  27.  
  28. const char  DocContent[] = "All";
  29. const char  DrawPadFormat[] = "DrawPad";
  30.  
  31. BEGIN_REGISTRATION(DocReg)
  32.   REGDATA(progid,     "DrawPad.Drawing.17")
  33.   REGDATA(description,"DrawPad (Step17--AutoContServer) Drawing")
  34.   REGDATA(menuname,   "Drawing")
  35.   REGDATA(extension,  "p17")
  36.   REGDATA(docfilter,  "*.p17")
  37.   REGDOCFLAGS(dtAutoOpen | dtAutoDelete | dtUpdateDir | dtCreatePrompt | dtRegisterExt)
  38. REGDATA(debugger,   "tdw -do")
  39. REGDATA(debugprogid,"DrawPad.Drawing.D.17")
  40. REGDATA(debugdesc,  "DrawPad (Step17--AutoContServer, debug) Drawing")
  41.   REGDATA(insertable, "")
  42.   REGDATA(verb0,      "&Edit")
  43.   REGDATA(verb1,      "&Open")
  44.   REGFORMAT(0, DrawPadFormat,   ocrContent,  ocrHGlobal,              ocrGetSet)
  45.   REGFORMAT(1, ocrEmbedSource,  ocrContent,  ocrIStorage,             ocrGetSet)
  46.   REGFORMAT(2, ocrMetafilePict, ocrContent,  ocrMfPict|ocrStaticMed,  ocrGet)
  47.   REGFORMAT(3, ocrBitmap,       ocrContent,  ocrGDI|ocrStaticMed,     ocrGet)
  48.   REGFORMAT(4, ocrDib,          ocrContent,  ocrHGlobal|ocrStaticMed, ocrGet)
  49. END_REGISTRATION
  50. BEGIN_REGISTRATION(ListReg)
  51.   REGDATA(description,"Line List")
  52.   REGDATA(extension,  "p17")
  53.   REGDATA(docfilter,  "*.p17")
  54.   REGDOCFLAGS(dtAutoDelete | dtHidden)
  55. END_REGISTRATION
  56.  
  57. DEFINE_DOC_TEMPLATE_CLASS(TDrawDocument, TDrawView,       DrawTemplate);
  58. DEFINE_DOC_TEMPLATE_CLASS(TDrawDocument, TDrawListView,   DrawListTemplate);
  59. DrawTemplate drawTpl(DocReg);
  60. DrawListTemplate drawListTpl(ListReg);
  61.  
  62. //===============================  TLine  =====================================
  63. //
  64. void
  65. TLine::SetPen(int penSize)
  66. {
  67.   if (penSize < 1)
  68.     PenSize = 1;
  69.   else
  70.     PenSize = penSize;
  71. }
  72.  
  73. void
  74. TLine::SetPen(const TColor& newColor, int penSize)
  75. {
  76.   // If penSize isn't the default (0), set PenSize to the new size.
  77.   if (penSize)
  78.     PenSize = penSize;
  79.  
  80.   Color = newColor;
  81. }
  82.  
  83. void
  84. TLine::Invalidate(TDrawView& view)
  85. {
  86.   TOleClientDC dc(view);
  87.  
  88.   TRect rUpdate(GetBound());
  89.   rUpdate.Inflate(1, 1);
  90.   dc.LPtoDP((TPoint *)&rUpdate, 2);
  91.   TUIHandle handle(rUpdate, TUIHandle::Framed);
  92.   rUpdate = handle.GetBoundingRect();
  93.  
  94.   view.GetDocument().NotifyViews(vnInvalidate, (long)&rUpdate, 0);
  95. }
  96.  
  97. void
  98. TLine::UpdateBound()
  99. {
  100.   // Iterates through the points in the line i.
  101.   TPointsIterator j(*this);
  102.   if (!j)
  103.     return;
  104.   TPoint p = j++;
  105.   Bound.Set(p.x, p.y, 0, 0);
  106.  
  107.   while (j) {
  108.     p = j++;
  109.    if ((p.x - PenSize) < Bound.left)
  110.      Bound.left = (p.x - PenSize);
  111.    if ((p.x + PenSize) > Bound.right)
  112.      Bound.right = (p.x + PenSize);
  113.    if ((p.y - PenSize) < Bound.top)
  114.      Bound.top = (p.y - PenSize);
  115.    if ((p.y + PenSize) > Bound.bottom)
  116.      Bound.bottom = (p.y + PenSize);
  117.   }
  118.   Bound.right  += 1;
  119.   Bound.bottom += 1;
  120. }
  121.  
  122. void
  123. TLine::UpdatePosition(TPoint& newPos)
  124. {
  125.   for (TPointsIterator i(*this); i; i++) {
  126.     TPoint* pt = (TPoint *)&i.Current();
  127.     pt->x += newPos.x;
  128.     pt->y += newPos.y;
  129.   }
  130.  
  131.   Bound.Offset(newPos.x, newPos.y);
  132. }
  133.  
  134. void
  135. TLine::UpdateSize(TSize& newSize)
  136. {
  137.   TSize delta = newSize - GetSize();
  138.   for (TPointsIterator i(*this); i; i++) {
  139.     TPoint* pt = (TPoint *)&i.Current();
  140.     pt->x += (((pt->x - Bound.left) * delta.cx + (GetSize().cx >> 1))/GetSize().cx);
  141.     pt->y += (((pt->y - Bound.top) * delta.cy + (GetSize().cy >> 1))/GetSize().cy);
  142.   }
  143.  
  144.   Bound.right = Bound.left + newSize.cx;
  145.   Bound.bottom = Bound.top  + newSize.cy;
  146. }
  147.  
  148. void
  149. TLine::DrawSelection(TDC &dc)
  150. {
  151.   TUIHandle(Bound, TUIHandle::DashFramed).Paint(dc);
  152. }
  153.  
  154. bool
  155. TLine::Draw(TDC& dc) const
  156. {
  157.   // Set pen for the dc to the values for this line
  158.   TPen pen(Color, PenSize, PS_INSIDEFRAME);
  159.   dc.SelectObject(pen);
  160.  
  161.   // Iterates through the points in the line i.
  162.   TPointsIterator j(*this);
  163.   bool first = true;
  164.  
  165.   while (j) {
  166.     TPoint p = j++;
  167.  
  168.     if (!first)
  169.       dc.LineTo(p);
  170.     else {
  171.       dc.MoveTo(p);
  172.       first = false;
  173.     }
  174.   }
  175.   dc.RestorePen();
  176.   return true;
  177. }
  178.  
  179. ostream&
  180. operator <<(ostream& os, const TLine& line)
  181. {
  182.   // Write the number of points in the line
  183.   os << line.GetItemsInContainer();
  184.  
  185.   // Get and write pen attributes.
  186.   os << ' ' << line.Color << ' ' << line.PenSize;
  187.  
  188.   // Get an iterator for the array of points
  189.   TPointsIterator j(line);
  190.  
  191.   // While the iterator is valid (i.e. we haven't run out of points)
  192.   while(j)
  193.     // Write the point from the iterator and increment the array.
  194.     os << j++;
  195.   os << '\n';
  196.  
  197.   // return the stream object
  198.   return os;
  199. }
  200.  
  201. istream&
  202. operator >>(istream& is, TLine& line)
  203. {
  204.   unsigned numPoints;
  205.   is >> numPoints;
  206.  
  207.   COLORREF color;
  208.   int penSize;
  209.   is >> color >> penSize;
  210.   line.SetPen(TColor(color), penSize);
  211.  
  212.   while (numPoints--) {
  213.     TPoint point;
  214.     is >> point;
  215.     line.Add(point);
  216.   }
  217.  
  218.   // return the stream object
  219.   return is;
  220. }
  221.  
  222. DEFINE_AUTOCLASS(TDrawDocument)
  223.   EXPOSE_PROPRW(PenSize,    TAutoShort, "PenSize",    "Current pen size", 0)
  224.   EXPOSE_PROPRW(PenColor,   TAutoLong,  "PenColor",   "Current pen color", 0)
  225.   EXPOSE_METHOD(AddPoint,   TAutoVoid,  "AddPoint",   "Add a point to the current line", 0)
  226.    REQUIRED_ARG(            TAutoShort, "X")
  227.    REQUIRED_ARG(            TAutoShort, "Y")
  228.   EXPOSE_METHOD(AddLine,    TAutoVoid,  "AddLine",    "Add current line into drawing", 0)
  229.   EXPOSE_METHOD(ClearLine,  TAutoVoid,  "ClearLine",  "Erases current line", 0)
  230.   EXPOSE_APPLICATION(       TDrawApp,   "Application","Application object", 0)
  231. END_AUTOCLASS(TDrawDocument, tfNormal,  "TDrawDoc",   "Draw document class", 0)
  232.  
  233. TDrawDocument::TDrawDocument(TDocument* parent)
  234.   : TOleDocument(parent), UndoLine(0), UndoState(UndoNone)
  235. {
  236.   Lines         = new TLines(100, 0, 5);
  237.   AutoPenSize   = 1;
  238.   AutoPenColor  = RGB(0, 0, 0);
  239.   AutoLine      = new TLine(AutoPenColor, AutoPenSize);
  240.  
  241.   TScreenDC dc;
  242.  
  243.   // 8.5"" x 11" draw document
  244.   DocSize.cx = dc.GetDeviceCaps(LOGPIXELSX)* 85 / 10;
  245.   DocSize.cy = dc.GetDeviceCaps(LOGPIXELSY)* 11;
  246. }
  247.  
  248. TDrawDocument::~TDrawDocument()
  249. {
  250.   delete AutoLine;
  251.   delete Lines;
  252.   delete UndoLine;
  253. }
  254.  
  255. TLine*
  256. TDrawDocument::GetLine(TString& moniker)
  257. {
  258.   int index = atoi(moniker);
  259.   return GetLine(index);
  260. }
  261.  
  262. bool
  263. TDrawDocument::CommitSelection(TOleWindow& oleWin, void* userData)
  264. {
  265.   TOleDocument::CommitSelection(oleWin, userData);
  266.  
  267.   TDrawView* drawView = TYPESAFE_DOWNCAST(&oleWin, TDrawView);
  268.   TOutStream* os = OutStream(ofWrite);
  269.   if (!os || !drawView)
  270.     return false;
  271.  
  272.   // Make the line usable in a container by adjusting its origin
  273.   //
  274.   TLine* line = (TLine*)userData;
  275.   int i = line? 1 : 0;
  276.   TPoint newPos(Margin, Margin);
  277.   if (line) {
  278.     newPos -= line->GetBound().TopLeft();
  279.     line->UpdatePosition(newPos);
  280.   }
  281.  
  282.   // Write the number of lines in the figure
  283.   *os << i;
  284.  
  285.   // Append a description using a resource string
  286.   *os << ' ' << FileInfo << '\n';
  287.  
  288.   // Copy the current line from the iterator and increment the array.
  289.   if (line)
  290.     *os << *line;
  291.  
  292.   delete os;
  293.  
  294.   // restore line
  295.   //
  296.   if (line)
  297.     line->UpdatePosition(-newPos);
  298.  
  299.   //
  300.   // Commit the storage if it was opened in transacted mode
  301. //  TOleDocument::CommitTransactedStorage();
  302.  
  303.   return true;
  304. }
  305.  
  306. bool
  307. TDrawDocument::Commit(bool force)
  308. {
  309.   TOleDocument::Commit(force);
  310.  
  311.   TOutStream* os = OutStream(ofWrite);
  312.   if (!os)
  313.     return false;
  314.  
  315.   // Write the number of lines in the figure
  316.   *os << Lines->GetItemsInContainer();
  317.  
  318.   // Append a description using a resource string
  319.   *os << ' ' << FileInfo << '\n';
  320.  
  321.   // Get an iterator for the array of lines
  322.   TLinesIterator i(*Lines);
  323.  
  324.   // While the iterator is valid (i.e. we haven't run out of lines)
  325.   while (i) {
  326.     // Copy the current line from the iterator and increment the array.
  327.     *os << i++;
  328.   }
  329.   delete os;
  330.  
  331.   //
  332.   // Commit the storage if it was opened in transacted mode
  333.   TOleDocument::CommitTransactedStorage();
  334.   SetDirty(false);
  335.  
  336.   return true;
  337. }
  338.  
  339. bool
  340. TDrawDocument::Open(int mode, const char far* path)
  341. {
  342.   char fileinfo[100];
  343.  
  344.   TOleDocument::Open(mode, path);   // normally path should be null
  345.   if (GetDocPath()) {
  346.     TInStream* is = (TInStream*)InStream(ofRead);
  347.     if (!is)
  348.       return false;
  349.  
  350.     unsigned numLines;
  351.     *is >> numLines;
  352.     is->getline(fileinfo, sizeof(fileinfo));
  353.     while (numLines--) {
  354.       TLine line;
  355.       *is >> line;
  356.       line.UpdateBound();
  357.       Lines->Add(line);
  358.     }
  359.  
  360.     delete is;
  361.  
  362.     FileInfo = fileinfo;
  363.   } else {
  364.     FileInfo = string(*::Module,IDS_FILEINFO);
  365.   }
  366.   SetDirty(false);
  367.   UndoState = UndoNone;
  368.   return true;
  369. }
  370.  
  371. //
  372. // Read in the lines from a storage and put them at the location specified
  373. // by where
  374. //
  375. bool
  376. TDrawDocument::OpenSelection(int mode, const char far* path, TPoint far* where)
  377. {
  378.   char fileinfo[100];
  379.  
  380.   TOleDocument::Open(mode, path);   // normally path should be null
  381.   //if (GetDocPath()) {
  382.     TInStream* is = (TInStream*)InStream(ofRead);
  383.     if (!is)
  384.       return false;
  385.  
  386.     unsigned numLines;
  387.     *is >> numLines;
  388.     is->getline(fileinfo, sizeof(fileinfo));
  389.     while (numLines--) {
  390.       TLine line;
  391.       *is >> line;
  392.       if (where) {
  393.         TPoint newPos(where->x, where->y);
  394.         newPos -= line.GetBound().TopLeft();
  395.         line.UpdatePosition(newPos);
  396.       }
  397.       line.UpdateBound();
  398.       Lines->Add(line);
  399.     }
  400.  
  401.     delete is;
  402.  
  403.   if (GetDocPath()) {
  404.     FileInfo = fileinfo;
  405.   } else {
  406.     FileInfo = string(*::Module,IDS_FILEINFO);
  407.   }
  408.   SetDirty(false);
  409.   UndoState = UndoNone;
  410.   return true;
  411. }
  412.  
  413. bool
  414. TDrawDocument::Close()
  415. {
  416.   if (TOleDocument::Close()) {
  417.     Lines->Flush();
  418.     return true;
  419.   }
  420.  
  421.   return false;
  422. }
  423.  
  424. TLine*
  425. TDrawDocument::GetLine(uint index)
  426. {
  427.   return index < Lines->GetItemsInContainer() ? &(*Lines)[index] : 0;
  428. }
  429.  
  430. int
  431. TDrawDocument::AddLine(TLine& line)
  432. {
  433.   int index = Lines->GetItemsInContainer();
  434.   Lines->Add(line);
  435.   SetDirty(true);
  436.   NotifyViews(vnDrawAppend, index);
  437.   UndoState = UndoAppend;
  438.   return index;
  439. }
  440.  
  441. void
  442. TDrawDocument::DeleteLine(uint index)
  443. {
  444.   const TLine* oldLine = GetLine(index);
  445.   if (!oldLine)
  446.     return;
  447.   delete UndoLine;
  448.   UndoLine = new TLine(*oldLine);
  449.   Lines->Detach(index);
  450.   SetDirty(true);
  451.   NotifyViews(vnDrawDelete, index);
  452.   UndoState = UndoDelete;
  453. }
  454.  
  455. void
  456. TDrawDocument::ModifyLine(TLine& line, uint index)
  457. {
  458.   delete UndoLine;
  459.   UndoLine = new TLine((*Lines)[index]);
  460.   SetDirty(true);
  461.   (*Lines)[index] = line;
  462.   NotifyViews(vnDrawModify, index);
  463.   UndoState = UndoModify;
  464.   UndoIndex = index;
  465. }
  466.  
  467. void
  468. TDrawDocument::Clear()
  469. {
  470.   Lines->Flush();
  471.   NotifyViews(vnRevert, true);
  472. }
  473.  
  474. void
  475. TDrawDocument::Undo()
  476. {
  477.   switch (UndoState) {
  478.     case UndoAppend:
  479.       DeleteLine(Lines->GetItemsInContainer()-1);
  480.       return;
  481.     case UndoDelete:
  482.       AddLine(*UndoLine);
  483.       delete UndoLine;
  484.       UndoLine = 0;
  485.       return;
  486.     case UndoModify:
  487.       TLine* temp = UndoLine;
  488.       UndoLine = 0;
  489.       ModifyLine(*temp, UndoIndex);
  490.       delete temp;
  491.   }
  492. }
  493.  
  494. bool
  495. GetPenSize(TWindow* parent, TLine& line)
  496. {
  497.   char inputText[6];
  498.  
  499.   wsprintf(inputText, "%d", line.QueryPenSize());
  500.   if (TInputDialog(parent, "Line Thickness",
  501.                    "Input a new thickness:",
  502.                    inputText,
  503.                    sizeof(inputText)).Execute() != IDOK)
  504.     return false;
  505.   line.SetPen(atoi(inputText));
  506.  
  507.   if (line.QueryPenSize() < 1)
  508.     line.SetPen(1);
  509.  
  510.   return true;
  511. }
  512.  
  513. bool
  514. GetPenColor(TWindow* parent, TLine& line)
  515. {
  516.   TChooseColorDialog::TData colors;
  517.   static TColor custColors[16] =
  518.   {
  519.     0x010101L, 0x101010L, 0x202020L, 0x303030L,
  520.     0x404040L, 0x505050L, 0x606060L, 0x707070L,
  521.     0x808080L, 0x909090L, 0xA0A0A0L, 0xB0B0B0L,
  522.     0xC0C0C0L, 0xD0D0D0L, 0xE0E0E0L, 0xF0F0F0L
  523.   };
  524.  
  525.   colors.Flags = CC_RGBINIT;
  526.   colors.Color = TColor(line.QueryColor());
  527.   colors.CustColors = custColors;
  528.   if (TChooseColorDialog(parent, colors).Execute() != IDOK)
  529.     return false;
  530.   line.SetPen(colors.Color);
  531.   return true;
  532. }
  533.  
  534. DEFINE_RESPONSE_TABLE1(TDrawLinkView, TOleLinkView)
  535.   EV_VN_DRAWDELETE,
  536.   EV_VN_DRAWMODIFY,
  537. END_RESPONSE_TABLE;
  538.  
  539. TDrawLinkView::TDrawLinkView(TDocument& doc, TOcLinkView& view)
  540.   :TOleLinkView(doc, view)
  541. {
  542.   DrawDoc = TYPESAFE_DOWNCAST(&doc, TDrawDocument);
  543.   CHECK(DrawDoc);
  544. }
  545.  
  546. TDrawLinkView::~TDrawLinkView()
  547. {
  548. }
  549.  
  550. //
  551. // Line was modified
  552. //
  553. bool
  554. TDrawLinkView::VnModify(uint index)
  555. {
  556.   // Get the selection correspondign to the moniker
  557.   //
  558.   TLine * line = DrawDoc->GetLine(GetMoniker());
  559.   if (!line)
  560.     return false;
  561.  
  562.   // Notify the container
  563.   //
  564.   if (index == DrawDoc->GetLines()->Find(*line)) {
  565.     UpdateLinks();
  566.   }
  567.  
  568.   return true;
  569. }
  570.  
  571. //
  572. // Line was deleted
  573. //
  574. bool
  575. TDrawLinkView::VnDelete(uint index)
  576. {
  577.   // Get the selection correspondign to the moniker
  578.   //
  579.   TLine * line = DrawDoc->GetLine(GetMoniker());
  580.   if (!line)
  581.     return false;
  582.  
  583.   // Notify the container
  584.   //
  585.   if (index == DrawDoc->GetLines()->Find(*line)) {
  586.     UpdateLinks();
  587.   }
  588.   return true;
  589. }
  590.  
  591. DEFINE_RESPONSE_TABLE1(TDrawView, TOleView)
  592.   EV_WM_LBUTTONDOWN,
  593.   EV_WM_MOUSEMOVE,
  594.   EV_WM_LBUTTONUP,
  595.   EV_COMMAND(CM_PEN, CmPen),
  596.   EV_COMMAND_ENABLE(CM_PEN, CePen),
  597.   EV_COMMAND(CM_SELECT, CmSelect),
  598.   EV_COMMAND_ENABLE(CM_SELECT, CeSelect),
  599.   EV_COMMAND(CM_PENSIZE, CmPenSize),
  600.   EV_COMMAND(CM_PENCOLOR, CmPenColor),
  601.   EV_COMMAND(CM_EDITCLEAR, CmClear),
  602.   EV_COMMAND(CM_EDITUNDO, CmUndo),
  603.   EV_COMMAND(CM_EDITCUT, CmEditCut),
  604.   EV_COMMAND(CM_EDITCOPY, CmEditCopy),
  605.   EV_COMMAND_ENABLE(CM_EDITCUT, CeEditCut),
  606.   EV_COMMAND_ENABLE(CM_EDITCOPY, CeEditCopy),
  607.   EV_COMMAND(CM_ORGSIZE, CmOrgSize),
  608.   EV_COMMAND(CM_DOUBLESIZE, CmDoubleSize),
  609.   EV_COMMAND(CM_HALFSIZE, CmHalfSize),
  610.   EV_COMMAND_ENABLE(CM_ORGSIZE, CeOrgSize),
  611.   EV_COMMAND_ENABLE(CM_DOUBLESIZE, CeDoubleSize),
  612.   EV_COMMAND_ENABLE(CM_HALFSIZE, CeHalfSize),
  613.   EV_VN_COMMIT,
  614.   EV_VN_REVERT,
  615.   EV_VN_DRAWAPPEND,
  616.   EV_VN_DRAWDELETE,
  617.   EV_VN_DRAWMODIFY,
  618.  
  619.   EV_WM_SETFOCUS,
  620.   EV_OC_VIEWPARTSIZE,
  621.   EV_OC_VIEWSHOWTOOLS,
  622.   EV_OC_VIEWGETITEMNAME,
  623.   EV_OC_VIEWSETLINK,
  624.   EV_OC_VIEWCLIPDATA,
  625.  
  626. END_RESPONSE_TABLE;
  627.  
  628. TDrawView::TDrawView(TDrawDocument& doc, TWindow* parent)
  629. :
  630.   TOleView(doc, parent), DrawDoc(&doc)
  631. {
  632.   Selected  = 0;
  633.   Tool      = DrawPen;
  634.   ToolBar   = 0;
  635.  
  636.   Line = new TLine(TColor::Black, 1);
  637.   Attr.AccelTable = IDA_DRAWVIEW;
  638.   SetViewMenu(new TMenuDescr(IDM_DRAWVIEW));
  639.  
  640.   // Name our clipboard format
  641.   //
  642.   OcApp->AddUserFormatName("DrawPad Native Data", "Owl DrawPad native data", DrawPadFormat);
  643. }
  644.  
  645. void
  646. TDrawView::SetupWindow()
  647. {
  648.   TOleView::SetupWindow();
  649.  
  650.   // Scroll bars
  651.   Attr.Style |= WS_VSCROLL | WS_HSCROLL;
  652.  
  653.   Scroller = new TScroller(this, 1, 1, 0, 0);
  654.   AdjustScroller();
  655.  
  656.   // Set this option to force all embedded servers to open out of place
  657.   // GetOcView()->SetOption(voNoInPlace,true);
  658.  
  659.   // Set this option to force all embedded servers to open out of place
  660.   // when the container/server is inplace
  661.   // GetOcView()->SetOption(voNoNestedInPlace,true);
  662.  
  663. }
  664.  
  665. //
  666. // Adjust the Scroller range
  667. //
  668. void
  669. TDrawView::AdjustScroller()
  670. {
  671.   TDrawDocument *drawDoc = TYPESAFE_DOWNCAST(&GetDocument(), TDrawDocument);
  672.   CHECK(drawDoc);
  673.   TSize range = drawDoc->GetDocSize();
  674.  
  675.   // Use device unit for scroll range
  676.   //
  677.   TOleClientDC dc(*this);
  678.   dc.LPtoDP((TPoint*)&range);
  679.  
  680.   range -= GetClientRect().Size();
  681.   Scroller->SetRange(range.cx, range.cy);
  682. }
  683.  
  684. //
  685. // Reset scroller range.
  686. //
  687. void
  688. TDrawView::EvSize(UINT SizeType, TSize& Size)
  689. {
  690.   TOleView::EvSize(SizeType, Size);
  691.   if (SizeType != SIZEICONIC) {
  692.     AdjustScroller();
  693.   }
  694. }
  695.  
  696. static int
  697. Intersect(const TLine& line, void* param)
  698. {
  699.   TPoint*  pt = (TPoint*)param;
  700.   TLine &modify = const_cast<TLine&>(line);
  701.   if (modify.IsSelected()) {
  702.     modify.Where = TUIHandle(modify.GetBound(), TUIHandle::Framed).HitTest(*pt);
  703.   }
  704.   else {
  705.     if (modify.GetBound().Contains(*pt))
  706.       modify.Where = TUIHandle::MidCenter;
  707.     else
  708.       modify.Where = TUIHandle::Outside;
  709.   }
  710.  
  711.   return line.Where != TUIHandle::Outside;
  712. }
  713.  
  714. TLine*
  715. TDrawView::HitTest(TPoint& pt)
  716. {
  717.   return DrawDoc->GetLines()->LastThat(Intersect, &pt);
  718. }
  719.  
  720. bool
  721. TDrawView::ShowCursor(HWND /*wnd*/, uint hitTest, uint /*mouseMsg*/)
  722. {
  723.   TPoint pt;
  724.   GetCursorPos(pt);
  725.   ScreenToClient(pt);
  726.   if (Tool == DrawSelect) {
  727.     ::SetCursor(::LoadCursor(0, IDC_ARROW));
  728.     return true;
  729.   }
  730.  
  731.   if (Tool == DrawPen && (hitTest == HTCLIENT)) {
  732.     HCURSOR cur = ::LoadCursor(*GetModule(), MAKEINTRESOURCE(IDC_PENCIL));
  733.     ::SetCursor(cur);
  734.     return true;
  735.   }
  736.  
  737.   if (Tool == DrawPen && ((hitTest == HTHSCROLL) || (hitTest == HTVSCROLL))) {
  738.     ::SetCursor(::LoadCursor(0, IDC_ARROW));
  739.     return true;
  740.   }
  741.  
  742.   return false;
  743. }
  744.  
  745.  
  746. //
  747. // Let container know about the server view size in pixels
  748. //
  749. bool
  750. TDrawView::EvOcViewPartSize(TOcPartSize far& ps)
  751. {
  752.   TClientDC dc(*this);
  753.  
  754.   TRect rect(0, 0, 0, 0);
  755.   TLine* line = 0;
  756.   if (ps.Selection) {
  757.     if (ps.Moniker) {
  758.       if (strcmp(*ps.Moniker, OleStr(DocContent)) == 0)
  759.         line = 0; // whole document
  760.       else
  761.         line = DrawDoc->GetLine(*ps.Moniker);
  762.     }
  763.     else{
  764.       line = (TLine*) ps.UserData;
  765.     }
  766.   }
  767.  
  768.   if (line) {
  769.     *(TPoint*)&rect.left   = line->GetBound().TopLeft();
  770.     rect.right  = rect.left + line->GetBound().Width()  + 2 * Margin;
  771.     rect.bottom = rect.top  + line->GetBound().Height() + 2 * Margin;
  772.   }
  773.   else {
  774.     // a 2" x 2" extent for server
  775.     //
  776.     rect.right  = dc.GetDeviceCaps(LOGPIXELSX) * 2;
  777.     rect.bottom = dc.GetDeviceCaps(LOGPIXELSY) * 2;
  778.   }
  779.  
  780.   ps.PartRect = rect;
  781.   return true;
  782. }
  783.  
  784. bool
  785. TDrawView::EvOcViewShowTools(TOcToolBarInfo far& tbi)
  786. {
  787.   // Construct & create a control bar for show, destroy our bar for hide
  788.   //
  789.   if (tbi.Show) {
  790.     if (!ToolBar) {
  791.       ToolBar = new TControlBar(this);
  792.       ToolBar->Insert(*new TButtonGadget(CM_PENSIZE, CM_PENSIZE, TButtonGadget::Command));
  793.       ToolBar->Insert(*new TButtonGadget(CM_PENCOLOR, CM_PENCOLOR, TButtonGadget::Command));
  794.       ToolBar->Insert(*new TSeparatorGadget);
  795.       ToolBar->Insert(*new TButtonGadget(CM_PEN, CM_PEN, TButtonGadget::Exclusive));
  796.       ToolBar->Insert(*new TButtonGadget(CM_SELECT, CM_SELECT, TButtonGadget::Exclusive));
  797.       ToolBar->Insert(*new TButtonGadget(CM_ABOUT, CM_ABOUT, TButtonGadget::Command));
  798.       ToolBar->SetHintMode(TGadgetWindow::EnterHints);
  799.     }
  800.     ToolBar->Create();
  801.     tbi.HTopTB = (HWND)*ToolBar;
  802.   }
  803.   else {
  804.     if (ToolBar) {
  805.       ToolBar->Destroy();
  806.       delete ToolBar;
  807.       ToolBar = 0;
  808.     }
  809.   }
  810.   return true;
  811. }
  812.  
  813. //
  814. // Find the item name for whole doc or selection
  815. //
  816. bool
  817. TDrawView::EvOcViewGetItemName(TOcItemName& item)
  818. {
  819.   if (item.Selection) {
  820.     if (!Selected)
  821.       return false;
  822.     char name[32];
  823.     itoa(DrawDoc->GetLines()->Find(*Selected), name, 10);
  824.     item.Name = name;
  825.   }
  826.   else {
  827.     item.Name = "content"; // item name representing the whole document
  828.   }
  829.   return true;
  830. }
  831.  
  832.  
  833. //
  834. // Ask server to provide data according to the format in a handle
  835. //
  836. bool
  837. TDrawView::EvOcViewClipData(TOcFormatData far& formatData)
  838. {
  839.   if (strcmp(OleStr(formatData.Format.GetRegName()), OleStr(DrawPadFormat)) != 0)
  840.     return false; // not our clipboard format
  841.  
  842.   bool status = true;
  843.   if (formatData.Paste) { // Pasting native data
  844.     DrawDoc->SetHandle(ofReadWrite, formatData.Handle, false);
  845.     DrawDoc->OpenSelection(ofRead, 0, formatData.Where);
  846.     Invalidate();
  847.     // Restore the original storage
  848.     //
  849.     DrawDoc->RestoreStorage();
  850.  
  851.   }
  852.   else { // Copying native data
  853.     HANDLE data = GlobalAlloc(GHND|GMEM_SHARE, 0);
  854.     DrawDoc->SetHandle(ofReadWrite, data, true);
  855.  
  856.     // Copy the selection if the target format is "DrawPad"
  857.     //
  858.     if (formatData.UserData) {
  859.       status = DrawDoc->CommitSelection(*this, formatData.UserData);
  860.     }
  861.     else {
  862.       status = DrawDoc->Commit(true);
  863.     }
  864.  
  865.     formatData.Handle = data;
  866.     // Restore the original storage
  867.     //
  868.     DrawDoc->RestoreStorage();
  869.   }
  870.  
  871.   return status;
  872. }
  873.  
  874.  
  875. //
  876. // object selection
  877. //
  878. bool
  879. TDrawView::Select(uint modKeys, TPoint& point)
  880. {
  881.   if (Tool != DrawSelect)
  882.     return false;
  883.  
  884.   // Clicked in lines?
  885.   TLine *line = HitTest(point);
  886.   SetLineSelection(line);
  887.  
  888.   if (Selected) { // there is a selection
  889.     TOleView::SetSelection(0);
  890.     DragRect = line->GetBound();
  891.     DragRect.right++;
  892.     DragRect.bottom++;
  893.     DragHit = line->Where;
  894.     DragStart = DragPt = point;
  895.     if (!DragDC)
  896.       DragDC = new TOleClientDC(*this);
  897.  
  898.     DragDC->DrawFocusRect(DragRect);
  899.     SetCapture();
  900.     return true;
  901.   }
  902.   else
  903.     // Select OLE object, if any
  904.     return TOleView::Select(modKeys, point);
  905.  
  906. }
  907.  
  908. void
  909. TDrawView::EvLButtonDown(uint modKeys, TPoint& point)
  910. {
  911.   TOleView::EvLButtonDown(modKeys, point);
  912.   if (SelectEmbedded() || !DragDC)
  913.     return;
  914.  
  915.   if (Tool == DrawSelect) { // selection
  916. //    Select(modKeys, point);
  917.   }
  918.   else if (Tool == DrawPen) {
  919.     SetCapture();
  920.     Pen = new TPen(Line->QueryColor(), Line->QueryPenSize());
  921.     DragDC->SelectObject(*Pen);
  922.     DragRect.SetNull();
  923.     DragDC->MoveTo(point);
  924.     Line->Add(point);
  925.   }
  926. }
  927.  
  928. void
  929. TDrawView::EvMouseMove(uint modKeys, TPoint& point)
  930. {
  931.   TOleView::EvMouseMove(modKeys, point);
  932.   if (SelectEmbedded() || !DragDC)
  933.     return;
  934.  
  935.   if (Tool == DrawPen) {
  936.     DragDC->LineTo(point);
  937.     Line->Add(point);
  938.   }
  939.   else if (Selected && DragHit == TUIHandle::MidCenter &&
  940.     !InClient(*DragDC, point)) { // selection
  941.     DragDC->DrawFocusRect(DragRect);   // erase old rect
  942.  
  943.     // Start drag & drop
  944.     //
  945.     TOcDropAction outAction;
  946.     TOcDataProvider* ocData = new TOcDataProvider(*OcView, &DocReg, 0,
  947.                                                   (void*)Selected, CleanUp);
  948.     OcApp->Drag(ocData, TOcDropAction(daDropCopy|daDropMove|daDropLink),
  949.                 outAction);
  950.  
  951.     if (outAction == daDropMove) {
  952.       DrawDoc->DeleteLine(DrawDoc->GetLines()->Find(*Selected));
  953.       SetLineSelection(0);
  954.     }
  955.     ocData->Release();
  956.     DragHit = TUIHandle::Outside;
  957.   }
  958. }
  959.  
  960. void
  961. TDrawView::SetLineSelection(TLine *Line)
  962. {
  963.   if (Selected) {
  964.     Selected->Invalidate(*this);
  965.     Selected->Select(false);
  966.   }
  967.   Selected = Line;
  968.   if (Selected) {
  969.     Selected->Select(true);
  970.     Selected->Invalidate(*this);
  971.   }
  972. }
  973.  
  974. void
  975. TDrawView::SetLineSelection(int index)
  976. {
  977.   SetLineSelection(DrawDoc->GetLine(index));
  978. }
  979.  
  980. void TDrawView::EvLButtonUp(uint modKeys, TPoint& point)
  981. {
  982.   TPoint oldPoint = point;
  983.  
  984.   if (!DragDC)
  985.     return;
  986.  
  987.   if ((Tool == DrawSelect) && !SelectEmbedded()) {
  988.     if (Selected && DragHit == TUIHandle::MidCenter) {
  989.       Selected->Invalidate(*this);
  990.       DragDC->DPtoLP(&point);
  991.       TPoint newPos = point - DragStart;
  992.       Selected->UpdatePosition(newPos);
  993.       Selected->Invalidate(*this);
  994.       InvalidatePart(invView);
  995.       DragHit = TUIHandle::Outside;
  996.       ReleaseCapture();
  997.     }
  998.   } else if ((Tool == DrawPen) && !SelectEmbedded()) {
  999.     ReleaseCapture();
  1000.     if (Line->GetItemsInContainer() > 1) {
  1001.       Line->UpdateBound();
  1002.       DrawDoc->AddLine(*Line);
  1003.     }
  1004.  
  1005.     Line->Flush();
  1006.     delete Pen;
  1007.   }
  1008.  
  1009.   TOleView::EvLButtonUp(modKeys, oldPoint);
  1010. }
  1011.  
  1012. void
  1013. TDrawView::CePen(TCommandEnabler& ce)
  1014. {
  1015.   ce.SetCheck(Tool == DrawPen);
  1016. }
  1017.  
  1018. void
  1019. TDrawView::CeSelect(TCommandEnabler& ce)
  1020. {
  1021.   ce.SetCheck(Tool == DrawSelect);
  1022. }
  1023.  
  1024. void
  1025. TDrawView::CmPen()
  1026. {
  1027.   Tool = DrawPen;
  1028. }
  1029.  
  1030. void
  1031. TDrawView::CmSelect()
  1032. {
  1033.   Tool = DrawSelect;
  1034. }
  1035.  
  1036. void
  1037. TDrawView::CmPenSize()
  1038. {
  1039.   if (Selected) {
  1040.     GetPenSize(this, *Selected);
  1041.     Selected->UpdateBound();
  1042.     DrawDoc->ModifyLine(*Selected, DrawDoc->GetLines()->Find(*Selected));
  1043.   }
  1044.   else
  1045.     GetPenSize(this, *Line);
  1046. }
  1047.  
  1048. void
  1049. TDrawView::CmPenColor()
  1050. {
  1051.   if (Selected) {
  1052.     GetPenColor(this, *Selected);
  1053.     DrawDoc->ModifyLine(*Selected, DrawDoc->GetLines()->Find(*Selected));
  1054.   }
  1055.   else
  1056.     GetPenColor(this, *Line);
  1057. }
  1058.  
  1059. void
  1060. TDrawView::CmOrgSize()
  1061. {
  1062.   SetScale(100);
  1063. }
  1064.  
  1065. void
  1066. TDrawView::CmDoubleSize()
  1067. {
  1068.   SetScale(200);
  1069. }
  1070.  
  1071. void
  1072. TDrawView::CmHalfSize()
  1073. {
  1074.   SetScale(50);
  1075. }
  1076.  
  1077. void
  1078. TDrawView::CeOrgSize(TCommandEnabler& ce)
  1079. {
  1080.   ce.SetCheck(!Scale.IsZoomed());
  1081. }
  1082.  
  1083. void
  1084. TDrawView::CeDoubleSize(TCommandEnabler& ce)
  1085. {
  1086.   ce.SetCheck(Scale.GetScale() == 200);
  1087. }
  1088.  
  1089. void
  1090. TDrawView::CeHalfSize(TCommandEnabler& ce)
  1091. {
  1092.   ce.SetCheck(Scale.GetScale() == 50);
  1093. }
  1094.  
  1095. void
  1096. TDrawView::CmClear()
  1097. {
  1098.   DrawDoc->Clear();
  1099. }
  1100.  
  1101. void
  1102. TDrawView::CmUndo()
  1103. {
  1104.   DrawDoc->Undo();
  1105. }
  1106.  
  1107. void
  1108. TDrawView::CeEditCut(TCommandEnabler& ce)
  1109. {
  1110.   ce.Enable(Selected != 0 || SelectEmbedded());
  1111. }
  1112.  
  1113. void
  1114. TDrawView::CeEditCopy(TCommandEnabler& ce)
  1115. {
  1116.   ce.Enable(Selected != 0 || SelectEmbedded());
  1117. }
  1118.  
  1119. //
  1120. // method to clean up the userdata passed to TOcDataProvider
  1121. //
  1122. void
  1123. TDrawView::CleanUp(void* /*userData*/)
  1124. {
  1125.   // No data clean up to do here
  1126. }
  1127.  
  1128. void
  1129. TDrawView::CmEditCut()
  1130. {
  1131.   if (Selected) {
  1132.     // Create a TOcDataProvider with current selection
  1133.     //
  1134.     TOcDataProvider* ocData = new TOcDataProvider(*OcView, &DocReg, 0,
  1135.                                                   (void*)Selected, CleanUp);
  1136.     OcApp->Copy(ocData);
  1137.  
  1138.     // Ask server to render its data before it's deleted
  1139.     //
  1140.     ocData->Disconnect();
  1141.     ocData->Release();
  1142.  
  1143.     // Delete the line
  1144.     //
  1145.     DrawDoc->DeleteLine(DrawDoc->GetLines()->Find(*Selected));
  1146.     SetLineSelection(0);
  1147.   }
  1148.   else
  1149.     TOleView::CmEditCut();
  1150. }
  1151.  
  1152. void
  1153. TDrawView::CmEditCopy()
  1154. {
  1155.   if (Selected) {
  1156.     // Create a TOcDataProvider with current selection
  1157.     //
  1158.     TOcDataProvider* ocData = new TOcDataProvider(*OcView, &DocReg, 0,
  1159.                                                   (void*)Selected, CleanUp);
  1160.     OcApp->Copy(ocData);
  1161.     ocData->Release();
  1162.   }
  1163.   else
  1164.     TOleView::CmEditCopy();
  1165. }
  1166.  
  1167. void
  1168. TDrawView::Paint(TDC& dc, bool /*erase*/, TRect& /*rect*/)
  1169. {
  1170.   bool metafile = (dc.GetDeviceCaps(TECHNOLOGY) == DT_METAFILE);
  1171.  
  1172.   // Iterates through the array of line objects.
  1173.   int j = 0;
  1174.   TLine* line;
  1175.   while ((line = const_cast<TLine *>(DrawDoc->GetLine(j++))) != 0) {
  1176.     line->Draw(dc);
  1177.     if (line->IsSelected() && !metafile)
  1178.       line->DrawSelection(dc);
  1179.   }
  1180. }
  1181.  
  1182. bool
  1183. TDrawView::PaintSelection(TDC& dc, bool /*erase*/, TRect& /*rect*/, void* userData)
  1184. {
  1185.   TLine* line = (TLine*) userData;
  1186.   if (!line)
  1187.     return false;
  1188.  
  1189.   TPoint newPos(Margin, Margin);
  1190.   newPos -= line->GetBound().TopLeft();
  1191.   line->UpdatePosition(newPos);
  1192.   line->Draw(dc);
  1193.   line->UpdatePosition(-newPos);
  1194.  
  1195.   return true;
  1196. }
  1197.  
  1198. // Establish link with whole doc or selection
  1199. //
  1200. bool
  1201. TDrawView::EvOcViewSetLink(TOcLinkView& view)
  1202. {
  1203.   // Attach a linked view to this document
  1204.   //
  1205.   new TDrawLinkView(GetDocument(), view);
  1206.   return true;
  1207. }
  1208.  
  1209. bool
  1210. TDrawView::PaintLink(TDC& dc, bool erase, TRect& rect, TString& moniker)
  1211. {
  1212.   //Draw the whole document if linking to the whole doc
  1213.   //
  1214.   if (strcmp(moniker, OleStr(DocContent)) == 0) {
  1215.     Paint(dc, erase, rect);
  1216.     return true;
  1217.   }
  1218.  
  1219.   // Find the selection with the corresponding moniker
  1220.   //
  1221.   TLine* line = DrawDoc->GetLine(moniker);
  1222.  
  1223.   if (!line)
  1224.     return false;
  1225.  
  1226.   TPoint newPos(Margin, Margin);
  1227.   newPos -= rect.TopLeft();
  1228.   line->UpdatePosition(newPos);
  1229.   line->Draw(dc);
  1230.   line->UpdatePosition(-newPos);
  1231.   return true;
  1232. }
  1233.  
  1234. bool
  1235. TDrawView::VnCommit(bool /*force*/)
  1236. {
  1237.   // nothing to do here, no data held in view
  1238.   return true;
  1239. }
  1240.  
  1241. bool
  1242. TDrawView::VnRevert(bool /*clear*/)
  1243. {
  1244.   Invalidate();  // force full repaint
  1245.   InvalidatePart(invView);
  1246.   return true;
  1247. }
  1248.  
  1249. bool
  1250. TDrawView::VnAppend(uint index)
  1251. {
  1252.   TLine* line = DrawDoc->GetLine(index);
  1253.   line->UpdateBound();
  1254.   line->Invalidate(*this);
  1255.   InvalidatePart(invView);
  1256.   return true;
  1257. }
  1258.  
  1259. bool
  1260. TDrawView::VnModify(uint /*index*/)
  1261. {
  1262.   Invalidate();  // force full repaint
  1263.   InvalidatePart(invView);
  1264.   return true;
  1265. }
  1266.  
  1267. bool
  1268. TDrawView::VnDelete(uint /*index*/)
  1269. {
  1270.   Invalidate();  // force full repaint
  1271.   InvalidatePart(invView);
  1272.   return true;
  1273. }
  1274.  
  1275. DEFINE_RESPONSE_TABLE1(TDrawListView, TListBox)
  1276.   EV_COMMAND(CM_PENSIZE, CmPenSize),
  1277.   EV_COMMAND(CM_PENCOLOR, CmPenColor),
  1278.   EV_COMMAND(CM_EDITCLEAR, CmClear),
  1279.   EV_COMMAND(CM_EDITUNDO, CmUndo),
  1280.   EV_COMMAND(CM_EDITDELETE, CmDelete),
  1281.   EV_VN_ISWINDOW,
  1282.   EV_VN_COMMIT,
  1283.   EV_VN_REVERT,
  1284.   EV_VN_DRAWAPPEND,
  1285.   EV_VN_DRAWDELETE,
  1286.   EV_VN_DRAWMODIFY,
  1287. END_RESPONSE_TABLE;
  1288.  
  1289. TDrawListView::TDrawListView(TDrawDocument& doc,TWindow *parent)
  1290.        : TView(doc), TListBox(parent, GetNextViewId(), 0,0,0,0), DrawDoc(&doc)
  1291. {
  1292.   Attr.Style &= ~(WS_BORDER | LBS_SORT);
  1293.   Attr.Style |= LBS_NOINTEGRALHEIGHT;
  1294.   Attr.AccelTable = IDA_DRAWLISTVIEW;
  1295.   SetViewMenu(new TMenuDescr(IDM_DRAWLISTVIEW));
  1296. }
  1297.  
  1298. bool
  1299. TDrawListView::CanClose()
  1300. {
  1301.   TView* curView = Doc->GetViewList();
  1302.   while (curView) {
  1303.     if (curView != this)
  1304.       return true;
  1305.  
  1306.     curView = curView->GetNextView();
  1307.   }
  1308.  
  1309.   return Doc->CanClose();
  1310. }
  1311.  
  1312. bool
  1313. TDrawListView::Create()
  1314. {
  1315.   TListBox::Create();
  1316.   LoadData();
  1317.   return true;
  1318. }
  1319.  
  1320. void
  1321. TDrawListView::LoadData()
  1322. {
  1323.   ClearList();
  1324.   int i = 0;
  1325.   const TLine* line;
  1326.   while ((line = DrawDoc->GetLine(i)) != 0)
  1327.     FormatData(line, i++);
  1328.  
  1329.   SetSelIndex(0);
  1330. }
  1331.  
  1332. void
  1333. TDrawListView::FormatData(const TLine* line, int unsigned index)
  1334. {
  1335.   char buf[80];
  1336.   TColor color(line->QueryColor());
  1337.   wsprintf(buf, "Color = R%d G%d B%d, Size = %d, Points = %d",
  1338.            color.Red(), color.Green(), color.Blue(),
  1339.            line->QueryPenSize(), line->GetItemsInContainer());
  1340.   DeleteString(index);
  1341.   InsertString(buf, index);
  1342.   SetSelIndex(index);
  1343. }
  1344.  
  1345. void
  1346. TDrawListView::CmPenSize()
  1347. {
  1348.   int index = GetSelIndex();
  1349.   const TLine* line = DrawDoc->GetLine(index);
  1350.   if (line) {
  1351.     TLine* newline = new TLine(*line);
  1352.     if (GetPenSize(this, *newline))
  1353.       DrawDoc->ModifyLine(*newline, index);
  1354.     delete newline;
  1355.   }
  1356. }
  1357.  
  1358. void
  1359. TDrawListView::CmPenColor()
  1360. {
  1361.   int index = GetSelIndex();
  1362.   const TLine* line = DrawDoc->GetLine(index);
  1363.   if (line) {
  1364.     TLine* newline = new TLine(*line);
  1365.     if (GetPenColor(this, *newline))
  1366.       DrawDoc->ModifyLine(*newline, index);
  1367.     delete newline;
  1368.   }
  1369. }
  1370.  
  1371. void
  1372. TDrawListView::CmClear()
  1373. {
  1374.   DrawDoc->Clear();
  1375. }
  1376.  
  1377. void
  1378. TDrawListView::CmUndo()
  1379. {
  1380.   DrawDoc->Undo();
  1381. }
  1382.  
  1383. void
  1384. TDrawListView::CmDelete()
  1385. {
  1386.   DrawDoc->DeleteLine(GetSelIndex());
  1387. }
  1388.  
  1389. bool
  1390. TDrawListView::VnCommit(bool /*force*/)
  1391. {
  1392.   return true;
  1393. }
  1394.  
  1395. bool
  1396. TDrawListView::VnRevert(bool /*clear*/)
  1397. {
  1398.   LoadData();
  1399.   return true;
  1400. }
  1401.  
  1402. bool
  1403. TDrawListView::VnAppend(uint index)
  1404. {
  1405.   const TLine* line = DrawDoc->GetLine(index);
  1406.   FormatData(line, index);
  1407.   SetSelIndex(index);
  1408.   return true;
  1409. }
  1410.  
  1411. bool
  1412. TDrawListView::VnDelete(uint index)
  1413. {
  1414.   DeleteString(index);
  1415.   HandleMessage(WM_KEYDOWN,VK_DOWN); // force selection
  1416.   return true;
  1417. }
  1418.  
  1419. bool
  1420. TDrawListView::VnModify(uint index)
  1421. {
  1422.   const TLine* line = DrawDoc->GetLine(index);
  1423.   FormatData(line, index);
  1424.   return true;
  1425. }
  1426.  
  1427. static char* PropNames[] = {
  1428.   "Line Count",      // LineCount
  1429.   "Description",       // Description
  1430. };
  1431.  
  1432. static int PropFlags[] = {
  1433.   pfGetBinary|pfGetText, // LineCount
  1434.   pfGetText,             // Description
  1435. };
  1436.  
  1437. const char*
  1438. TDrawDocument::PropertyName(int index)
  1439. {
  1440.   if (index <= PrevProperty)
  1441.     return TStorageDocument::PropertyName(index);  // OC server change
  1442.   else if (index < NextProperty)
  1443.     return PropNames[index-PrevProperty-1];
  1444.   else
  1445.     return 0;
  1446. }
  1447.  
  1448. int
  1449. TDrawDocument::PropertyFlags(int index)
  1450. {
  1451.   if (index <= PrevProperty)
  1452.     return TStorageDocument::PropertyFlags(index); // OC server change
  1453.   else if (index < NextProperty)
  1454.     return PropFlags[index-PrevProperty-1];
  1455.   else
  1456.     return 0;
  1457. }
  1458.  
  1459. int
  1460. TDrawDocument::FindProperty(const char far* name)
  1461. {
  1462.   for (int i=0; i < NextProperty-PrevProperty-1; i++)
  1463.     if (strcmp(PropNames[i], name) == 0)
  1464.       return i+PrevProperty+1;
  1465.   return 0;
  1466. }
  1467.  
  1468. int
  1469. TDrawDocument::GetProperty(int prop, void far* dest, int textlen)
  1470. {
  1471.   switch(prop) {
  1472.     case LineCount: {
  1473.       int count = Lines->GetItemsInContainer();
  1474.       if (!textlen) {
  1475.         *(int far*)dest = count;
  1476.         return sizeof(int);
  1477.       }
  1478.       return wsprintf((char far*)dest, "%d", count);
  1479.     }
  1480.     case Description:
  1481.       char* temp = new char[textlen]; // need local copy for medium model
  1482.       int len = FileInfo.copy(temp, textlen);
  1483.       strcpy((char far*)dest, temp);
  1484.       return len;
  1485.   }
  1486.   return TStorageDocument::GetProperty(prop, dest, textlen); // OC server change
  1487. }
  1488.